package com.jacobson.huobi.mvp


import android.annotation.SuppressLint
import android.content.ComponentName
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.content.pm.PackageManager
import android.media.AudioManager
import android.net.Uri
import android.os.*
import android.provider.Settings
import android.util.SparseArray
import android.view.LayoutInflater
import android.view.View
import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.viewpager.widget.ViewPager
import com.google.android.material.tabs.TabLayout
import com.jacobson.core.base.BaseActivity
import com.jacobson.core.base.Immersive
import com.jacobson.core.di.components.AppComponent
import com.jacobson.core.di.modules.ActivityModule
import com.jacobson.core.framework.delegation.WeakRef
import com.jacobson.core.mvp.IPresenter
import com.jacobson.core.utils.ImmersiveExtensions
import com.jacobson.core.widget.storage.GlobalStorage
import com.jacobson.huobi.Constants
import com.jacobson.huobi.Constants.NEED_LOGIN
import com.jacobson.huobi.HuobiApplication
import com.jacobson.huobi.R
import com.jacobson.huobi.common.BaseSelectableFragment
import com.jacobson.huobi.common.constants.CommonConstant
import com.jacobson.huobi.common.constants.WebsocketConnectConstant
import com.jacobson.huobi.common.expansion.toJson
import com.jacobson.huobi.di.components.DaggerMainActivityComponent
import com.jacobson.huobi.di.modules.RxPermissionModule
import com.jacobson.huobi.entities.SystemActiveInfo
import com.jacobson.huobi.entities.events.LoginEvent
import com.jacobson.huobi.entities.events.SystemActiveEvent
import com.jacobson.huobi.entities.events.WebsocketEvent
import com.jacobson.huobi.entities.vo.LoginRespVo
import com.jacobson.huobi.entities.websocket.RefreshSystemStatusResp
import com.jacobson.huobi.mvp.adapters.MainAdapter
import com.jacobson.huobi.mvp.fragment.HomeFragment
import com.jacobson.huobi.mvp.fragment.MeFragment
import com.jacobson.huobi.mvp.fragment.SymbolFragment
import com.jacobson.huobi.services.WebsocketService
import com.jacobson.huobi.threads.TokenThread
import com.jacobson.huobi.utils.*
import com.jacobson.huobi.websocket.ProtocolFactory
import com.jacobson.huobi.websocket.WebsocketManager
import com.tbruyelle.rxpermissions2.RxPermissions
import io.reactivex.disposables.Disposable
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.item_db_header.*
import kotlinx.android.synthetic.main.item_main_tab.view.*
import org.simple.eventbus.EventBus
import org.simple.eventbus.Subscriber
import java.io.File
import javax.inject.Inject


/**
 * ================================================
 * 主界面
 * @author Wucz on 2018/7/16 14:43
 * ================================================
 */
@Immersive(fitSystemWindows = false)
class MainActivity : BaseActivity() {
    @Inject
    lateinit var rxPermissions: RxPermissions
    private var disposable: Disposable? = null

    private var handler: Handler? = null

    private var loginRespVo: LoginRespVo? = null

    private var imessage: Boolean = true

    private  var mFile: File? = null
    override fun setupActivityComponent(appComponent: AppComponent) {
        DaggerMainActivityComponent.builder()
                .activityModule(ActivityModule(this))
                .rxPermissionModule(RxPermissionModule())
                .appComponent(appComponent)
                .build()
                .inject(this)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 给window设置音频流
        volumeControlStream = AudioManager.STREAM_ALARM
        //修改底部功能键背景色 只支持api为21及以上
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            window.navigationBarColor =
                    ResourcesUtil.getColor(R.color.colorPrimary) //设定底部导航栏  同全局颜色
        }

    }


    @RequiresApi(api = Build.VERSION_CODES.M)
    private fun isIgnoringBatteryOptimizations(): Boolean {
        var isIgnoring = false
        val powerManager = getSystemService(Context.POWER_SERVICE) as? PowerManager
        if (powerManager != null) {
            isIgnoring = powerManager.isIgnoringBatteryOptimizations(packageName)
        }
        return isIgnoring
    }

    @RequiresApi(api = Build.VERSION_CODES.M)
    fun requestIgnoreBatteryOptimizations() {
        try {
            val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)
            intent.data = Uri.parse("package:$packageName")
            startActivity(intent)
        } catch (e: Exception) {
            e.printStackTrace()
        }

    }

    override fun initView(savedInstanceState: Bundle?): Int = R.layout.activity_main

    override fun initData(savedInstanceState: Bundle?) {
//        AndroidBug5497Workaround.assistActivity(this)
        bnve.enableShiftingMode(false)
        viewpager.offscreenPageLimit = 5
        viewpager.adapter = MainAdapter(supportFragmentManager)
        bnve.setOnNavigationItemSelectedListener {
            var position = 0
            when (it.itemId) {
                R.id.menu_1 -> position = 0
                R.id.menu_2 -> position = 1
                R.id.menu_3 -> position = 2
                R.id.menu_4 -> position = 3
                R.id.menu_5 -> position = 4
            }
            if (viewpager.currentItem != position) {
                viewpager.setCurrentItem(position, false)
            }
            return@setOnNavigationItemSelectedListener true
        }
        viewpager.addOnPageChangeListener(TabViewOnPageChangeListener())

//        initTabFrame()
        initHandler()
        autoStartDialog()

        requestPermissions()



        GlobalStorage.put(CommonConstant.KEY_SEL_MARKET, TAB_VALUE_RES_IDS[POSITION_SYMBOL_HUOBI])
        GlobalStorage.put(CommonConstant.KEY_SEL_VOLUME_LEVEL, "1")

        EventBus.getDefault().post(LoginEvent(2, null))

    }
    private inner class TabViewOnPageChangeListener : ViewPager.OnPageChangeListener {
        override fun onPageScrollStateChanged(state: Int) {
        }

        override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
        }

        override fun onPageSelected(position: Int) {
            bnve.currentItem = position
        }
    }
    @Subscriber
    fun onWebsocketEvent(event: WebsocketEvent) {
        if (imessage) {
            tvMainNetworkStatus.visibility = View.GONE
            if (event.type == WebsocketConnectConstant.CONNECT_DISCONNECT ||
                    event.type == WebsocketConnectConstant.CONNECT_ERROR ||
                    event.type == WebsocketConnectConstant.CONNECT_TIMEOUT
            ) {
                tvMainNetworkStatus.visibility = View.VISIBLE
                tvMainNetworkStatus.text = event.message
            } else if (event.type == WebsocketConnectConstant.CONNECTING) {
                var arrayList: IntArray = event.args as IntArray
                tvMainNetworkStatus.visibility = View.VISIBLE
                tvMainNetworkStatus.text =
                        "连接中,第" + (arrayList[1] + 1) + "次重连," + "倒计时" + (arrayList[0]) + "秒重连"
            } else if (event.type == WebsocketConnectConstant.CONNECTED) {
                tvMainNetworkStatus.visibility = View.VISIBLE
                tvMainNetworkStatus.text = event.message
                Thread(object : Runnable {
                    override fun run() {
                        Thread.sleep(3000)
                        handler?.sendEmptyMessage(0)
                    }
                }).start()
            }
            logger.d(event.toJson())
        }
    }

    @Subscriber
    @Suppress("UNCHECKED_CAST")
    private fun onRefreshSystemStatusResp(systemStatusResp: RefreshSystemStatusResp) {
        val localList = GlobalStorage.get(Constants.KEY_SYSTEM_STATUS) as List<SystemActiveInfo>
        systemStatusResp.takeIf { it.code == 0 }?.data?.forEach { systemActiveInfo ->
            localList.find { it.id == systemActiveInfo.id }?.run {
                this.color = systemActiveInfo.color
                this.lastTs = systemActiveInfo.lastTs
                this.status = systemActiveInfo.status
            }
        }
        EventBus.getDefault().post(SystemActiveEvent())
    }

    //华为
    fun isHuawei(): Boolean {
        if (Build.BRAND == null) {
            return false;
        } else {
            return Build.BRAND.toLowerCase().equals("huawei") || Build.BRAND.toLowerCase().equals("honor");
        }
    }

    fun goHuaweiSetting() {
        try {
            showActivity(
                    "com.huawei.systemmanager",
                    "com.huawei.systemmanager.startupmgr.ui.StartupNormalAppListActivity"
            )
        } catch (e: Exception) {
            showActivity(
                    "com.huawei.systemmanager",
                    "com.huawei.systemmanager.optimize.bootstart.BootStartActivity"
            )
        }
    }

    //小米
    fun isXiaomi(): Boolean {
        return Build.BRAND != null && Build.BRAND.toLowerCase().equals("xiaomi");
    }

    fun goXiaomiSetting() {
        showActivity(
                "com.miui.securitycenter",
                "com.miui.permcenter.autostart.AutoStartManagementActivity"
        );
    }

    //oppo
    fun isOPPO(): Boolean {
        return Build.BRAND != null && Build.BRAND.toLowerCase().equals("oppo");
    }

    fun goOPPOSetting() {
        try {
            showActivity("com.coloros.phonemanager");
        } catch (e1: Exception) {
            try {
                showActivity("com.oppo.safe");
            } catch (e2: Exception) {
                try {
                    showActivity("com.coloros.oppoguardelf");
                } catch (e3: Exception) {
                    showActivity("com.coloros.safecenter");
                }
            }
        }
    }

    //VIVO
    fun isVIVO(): Boolean {
        return Build.BRAND != null && Build.BRAND.toLowerCase().equals("vivo");
    }

    fun goVIVOSetting() {
        showActivity("com.iqoo.secure");
    }

    //Meizu
    fun isMeizu(): Boolean {
        return Build.BRAND != null && Build.BRAND.toLowerCase().equals("meizu");
    }

    fun goMeizuSetting() {
        showActivity("com.meizu.safe");
    }

    //三星
    fun isSamsung(): Boolean {
        return Build.BRAND != null && Build.BRAND.toLowerCase().equals("samsung");
    }

    fun goSamsungSetting() {
        try {
            showActivity("com.samsung.android.sm_cn");
        } catch (e: Exception) {
            showActivity("com.samsung.android.sm");
        }
    }

    //乐视
    fun isLeTV(): Boolean {
        return Build.BRAND != null && Build.BRAND.toLowerCase().equals("letv");
    }

    fun goLetvSetting() {
        showActivity(
                "com.letv.android.letvsafe",
                "com.letv.android.letvsafe.AutobootManageActivity"
        );
    }

    //锤子
    fun isSmartisan(): Boolean {
        return Build.BRAND != null && Build.BRAND.toLowerCase().equals("smartisan");
    }

    fun goSmartisanSetting() {
        showActivity("com.smartisanos.security");
    }


    /**
     * 跳转到指定应用的首页
     */
    private fun showActivity(phoneNumber: String) {
        startActivity(getPackageManager().getLaunchIntentForPackage(packageName));
    }

    /**
     * 跳转到指定应用的指定页面
     */
    private fun showActivity(packageName: String, activityDir: String) {
        intent.setComponent(ComponentName(packageName, activityDir));
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);
    }


    override fun onStart() {
        super.onStart()
        if (TokenStorageUtil.read()==null&&NEED_LOGIN){
            LoginActivity.startActivity(this)

        }

        // 主页在前台
        GlobalStorage.put(Constants.KEY_IS_MAIN_FRONT, true)
        // 退出保活前台服务
        KeepLiveManager.stopForegroundService()
        // 订阅
        WebsocketManager.sendMessage(ProtocolFactory.ofSubscribe())
        TokenThread.start()
        loginRespVo = TokenStorageUtil.read()

        if (loginRespVo != null) {
            WebsocketManager.sendMessage(ProtocolFactory.ofCommitAccessToken(loginRespVo!!.accessToken))
        } else {
            Toast.makeText(this, "请先登录", Toast.LENGTH_SHORT).show()
        }
        imessage = true
    }

    override fun onStop() {
        super.onStop()
        // 主页退出前台
        GlobalStorage.put(Constants.KEY_IS_MAIN_FRONT, false)
        // 启动保活前台服务
        KeepLiveManager.startForegroundService()
        // 取消订阅
        WebsocketManager.sendMessage(ProtocolFactory.ofUnSubscribe())
        TokenThread.stop()
        imessage = false;
    }

    override fun onResume() {
        super.onResume()
        KeepLiveManager.finishOnePxActivity()
    }


//    private fun showTab(position: Int) {
//        mainFrameTabLayout.getTabAt(position)?.select()
//        logger.d("MainActivity: ShowTab = $position")
//    }

    override fun doOnExit() {
        super.doOnExit()
        disposable?.takeIf { !it.isDisposed }?.dispose()
    }



    private var lastContainer: BaseSelectableFragment<*> = HomeFragment.getInstance()

    private fun showCurrentFragment(position: Int) {
        supportFragmentManager.beginTransaction()
            .hide(lastContainer)
            .show(fetchFragment(position))
            .commit()
        lastContainer.unSelect()
        lastContainer = fetchFragment(position)
        lastContainer.select()
        ImmersiveExtensions.immersive(lastContainer)
//        tvMainNetworkStatus.text = "1111"
//        tvMainShowNetworkStatus.bringToFront()
    }

    @SuppressLint("InflateParams")
    private fun obtainTabItemView(position: Int): View {
        val inflater = LayoutInflater.from(this)
        val tabView = inflater.inflate(R.layout.item_main_tab, null, false)
        tabView.mainTabName.text = TAB_NAME_RES_IDS[position]
        tabView.mainTabIcon.setImageResource(TAB_ICONS[position])
        return tabView
    }

    private fun setTabItemTabSelectedState(tab: TabLayout.Tab?, isSelected: Boolean) {
        logger.d("setTabItemTabSelectedState: $isSelected ${tab?.position}, ${tab?.text}, ${tab?.customView},${tab?.customView?.mainTabName},${tab?.customView?.mainTabIcon}")
        tab?.customView?.mainTabName?.let {
            if (isSelected != it.isSelected) {
                it.isSelected = isSelected
            }
        }
        tab?.customView?.mainTabIcon?.let {
            if (isSelected != it.isSelected) {
                it.isSelected = isSelected
            }
        }
    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
    }

    override fun useEventBus() = true
    /*fun updateAppDialog(){
        val Dialog = android.app.AlertDialog.Builder(this@MainActivity).create()
        //必须是android.app.AlertDialog.Builder 否则alertDialog.show()会报错
        Dialog.setTitle("温馨提示")
        Dialog.setMessage("为了及时收到我们推送消息，我们建议去系统设置中允许后台运行，是否去设置？")
        Dialog.setCancelable(false)//用于屏蔽返回键和点击空白处
        Dialog.setButton(DialogInterface.BUTTON_POSITIVE, "下次升级")
        { dialog, _ ->
            dialog.dismiss()
        }
        Dialog.setButton(DialogInterface.BUTTON_NEGATIVE, "现在升级")
        { dialog, _ ->
            loadNewVersionProgress("")
            dialog.dismiss()

        }
        Dialog.show()
    }
    private fun loadNewVersionProgress(upLoadUrl: String) {
        val pd: ProgressDialog
        pd = ProgressDialog(this)
        pd.setCancelable(false)
        pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL)
        pd.setMessage("正在下载更新")
        pd.show()
        Thread(Runnable {
            try {
                mFile = getFileFromServer(upLoadUrl, pd)
                SystemClock.sleep(2000)
                mFile?.let { applyInstallCheck(it) }
                pd.dismiss()
            } catch (e: java.lang.Exception) {
                e.printStackTrace()
                pd.dismiss()
            }
        }).start()
    }
    @Throws(java.lang.Exception::class)
    fun getFileFromServer(
        path: String?,
        pd: ProgressDialog
    ): File? { //如果相等的话表示当前的sdcard挂载在手机上并且是可用的
        return if (Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED) {
            val url = URL(path)
            val conn =
                url.openConnection() as HttpURLConnection
            conn.connectTimeout = 5000
            //获取到文件的大小
            pd.max = conn.contentLength
            val `is` = conn.inputStream
            val file =
                File(Environment.getExternalStorageDirectory(), "updata.apk")
            val fos = FileOutputStream(file)
            val bis = BufferedInputStream(`is`)
            val buffer = ByteArray(1024)
            var len: Int
            var total = 0
            while (bis.read(buffer).also { len = it } != -1) {
                fos.write(buffer, 0, len)
                total += len
                //获取当前下载量
                pd.progress = total
            }
            fos.close()
            bis.close()
            `is`.close()
            file
        } else {
            null
        }
    }
    private fun applyInstallCheck(file: File) {
        installApk(file)
    }
    protected fun installApk(file: File?) {
        if (file != null) {
            val intent = Intent()
            intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
            intent.action = Intent.ACTION_VIEW
            intent.setDataAndType(
                Uri.fromFile(file),
                "application/vnd.android.package-archive"
            )
            startActivity(intent)
            Process.killProcess(Process.myPid())
        } else {
            Toast.makeText(this, "安装包解析异常，请稍后重试", Toast.LENGTH_LONG).show()
        }
    }*/
    private fun autoStartDialog(){

        if (PreferencesUtil.getBoolean("autoBackFirst",false)){
            return
        }
        val Dialog = android.app.AlertDialog.Builder(this@MainActivity).create()
        //必须是android.app.AlertDialog.Builder 否则alertDialog.show()会报错
        Dialog.setTitle("温馨提示")
        Dialog.setMessage("为了及时收到我们推送消息，我们建议去系统设置中允许后台运行，是否去设置？")
        Dialog.setCancelable(false)//用于屏蔽返回键和点击空白处
        Dialog.setButton(DialogInterface.BUTTON_POSITIVE, "不设置谢谢")
        { dialog, _ ->
            PreferencesUtil.saveValue("autoBackFirst",true)
            dialog.dismiss()
        }
        Dialog.setButton(DialogInterface.BUTTON_NEGATIVE, "去设置")
        { dialog, _ ->
            PreferencesUtil.saveValue("autoBackFirst",true)
            dialog.dismiss()
            if (isHuawei()) {
                goHuaweiSetting()
            } else if (isXiaomi()) {
                goXiaomiSetting()
            } else if (isOPPO()) {
                goOPPOSetting()
            } else if (isVIVO()) {
                goVIVOSetting()
            } else if (isMeizu()) {
                goMeizuSetting()
            } else if (isSamsung()) {
                goSamsungSetting()
            } else if (isLeTV()) {
                goLetvSetting()
            } else if (isSmartisan()) {
                goSmartisanSetting()
            }else{
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    requestIgnoreBatteryOptimizations()
                }
            }
        }
        Dialog.show()
    }

    private fun requestPermissions() {
        disposable?.takeIf { !it.isDisposed }?.dispose()
        disposable = PermissionHelper.fetchAppPermission(rxPermissions)
                .subscribe({
                    startService(Intent(this, WebsocketService::class.java))
                }, {
                    Toast.makeText(this, "无权限", Toast.LENGTH_SHORT).show()
                })

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (PreferencesUtil.getBoolean("battery",false)){
                return
            }
            if (!isIgnoringBatteryOptimizations()) {
                var intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
                intent.setData(Uri.parse("package:"+getPackageName()));
                startActivity(intent);
            }
        }
    }

    private fun clearTips() {
        tvRelaTimeCount.text = ""
    }

    private fun initHandler() {
        handler = Handler {
            if (it.what == 0) {
                tvMainNetworkStatus.text = ""
                tvMainNetworkStatus.visibility = View.GONE
            }
            true
        }
    }

    companion object {

        internal const val TAB_SIZE = 5
        internal val TAB_NAME_RES_IDS =
            HuobiApplication.getInstance().resources.getStringArray(R.array.arr_tab_name)
        internal val TAB_VALUE_RES_IDS =
            HuobiApplication.getInstance().resources.getStringArray(R.array.arr_tab_value)
        internal val TAB_ICONS = arrayOf(
            R.drawable.selector_tab_item_me,
            R.drawable.selector_tab_item_me, R.drawable.selector_tab_item_me,
            R.drawable.selector_tab_item_me, R.drawable.selector_tab_item_me
        )

        private const val KEY_OF_POSITION: String = "__KEY_OF_POSITION__"
        //        const val POSITION_HOME: Int = 0
        const val POSITION_SYMBOL_HUOBI: Int = 0
        const val POSITION_SYMBOL_OKEX: Int = 1
        const val POSITION_SYMBOL_BIAN: Int = 2
        const val POSITION_SYMBOL_COIN_58: Int = 3
        const val POSITION_ME: Int = 4

        // 缓存Fragment
        private val weakRefFragmentCachedMap =
            SparseArray<BaseSelectableFragment<out IPresenter>>(5)

        @Synchronized
        private fun fetchFragment(position: Int): BaseSelectableFragment<out IPresenter> {
            if (weakRefFragmentCachedMap[position] == null) {
                val fragment by WeakRef {
                    when (position) {
                        POSITION_SYMBOL_OKEX -> SymbolFragment.newInstance(SymbolFragment.OKEX)
                        POSITION_SYMBOL_BIAN -> SymbolFragment.newInstance(SymbolFragment.BIAN)
                        POSITION_SYMBOL_COIN_58 -> SymbolFragment.newInstance(SymbolFragment.COIN_58)
                        POSITION_ME -> MeFragment.newInstance()
                        else -> SymbolFragment.newInstance(SymbolFragment.HUOBI)
                    }
                }
                weakRefFragmentCachedMap.put(position, fragment)
            }
            return weakRefFragmentCachedMap[position]
        }

        fun startHomeActivity(context: Context, position: Int = 0) {
            val intent = Intent(context, MainActivity::class.java).apply {
                putExtras(Bundle().apply {
                    this.putInt(KEY_OF_POSITION, position)
                })
            }
            intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP
            context.startActivity(intent)
        }
    }

    /**
     * 获取版本号
     *
     * @param context 上下文
     *
     * @return 版本号
     */
    fun getVersionCode(context: Context): Int { //获取包管理器
        val pm = context.packageManager
        //获取包信息
        try {
            val packageInfo = pm.getPackageInfo(context.packageName, 0)
            //返回版本号
            return packageInfo.versionCode
        } catch (e: PackageManager.NameNotFoundException) {
            e.printStackTrace()
        }
        return 0
    }
}
